package com.runjian.rundo.iot.agent.iec104.parser.frame.control.system;

import java.util.Date;
import java.util.List;

import cn.hutool.core.collection.ListUtil;
import com.runjian.rundo.iot.agent.iec104.consts.Action;
import com.runjian.rundo.iot.agent.iec104.consts.Cot;
import com.runjian.rundo.iot.agent.iec104.consts.Ti;
import com.runjian.rundo.iot.agent.iec104.parser.frame.ASDUFrame;
import com.runjian.rundo.iot.agent.iec104.parser.frame.Cp56Time2a;
import com.runjian.rundo.iot.agent.iec104.parser.frame.InfoElement;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ByteUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * C_CS_NA_1(103, "时钟同步/读取命令")
 *
 * @author CaoQingHua
 */
@Getter
@Setter
@Slf4j
public class C_CS_NA_1 extends ASDUFrame {

    @Override
    public void init() {
        // 激活确认
        this.setCot(Cot.ACT);
        // 类型
        this.setTi(Ti.C_CS_NA_1);
        // 初始化一个信息元素
        InfoElement infoElement = InfoElement.<Void>builder().address(0).date(Cp56Time2a.of(DateUtil.date())).build();
        this.addInfoElement(infoElement);
    }

    @Override
    public void analysisInfo(byte[] msg) {
        this.addInfoElement(InfoElement.builder().address(ByteUtil.bytesToInt(new byte[] {msg[12], msg[13], msg[14], 0x00}))
            .date(Cp56Time2a.of(ArrayUtil.sub(msg, 15, 22))).build());
    }

    /**
     * 针对从站发送的数据，进行校验
     * 
     * @return
     */
    @Override
    public ASDUFrame replyFrame() {
        ASDUFrame frame = null;
        if (this.getCot() == Cot.ACTCON || this.getCot() == Cot.REQ) {
            // 时钟确认,检测时间
            InfoElement<Void> infoElement = this.getInfoElements().get(0);
            // 主站时间
            Date date = DateUtil.date();
            // 相差的秒数
            Long second = DateUtil.between(date, infoElement.getDate(), DateUnit.SECOND);
            if (log.isDebugEnabled()) {
                log.debug("从站时间与主站时间相差{}秒,主站时间:{},从站时间:{}", second, date, infoElement.getDate());
            }
            if (second > 5) {
                // 超过5秒，初始化本对象
                this.init();
                // 重新发送同步命令
                frame = this;
            }
        }
        return frame;
    }


    @Override
    public List<Action> action() {
        if(this.getCot()==Cot.ACTCON){
            //激活确认，发送S侦
            return ListUtil.of(Action.SEND_S_DETECT);
        }else{
            return null;
        }
    }
}
